﻿#pragma once
#include "classes.h"
#include "ReflectionException.h"
#include "LibraryNode.h"
#include "ValueNode.h"
#include "FunctionNode.h"
#include "TypeNode.h"
#include "NamespaceNode.h"
#include "TypeLibrary.h"
namespace LK
{
	namespace Reflection
	{
		PTypeLibrary GetGlobleLibrary();
		inline PString GetFullClassNameById(index_t id)
		{
			PTypeNode n = GetGlobleLibrary().GetTypeNodeByInfo(id);
			if (n.IsNull())
			{
				return Type::GetTypeCommonInfoRef()[id].Name;
			}
			return n.GetFullName();
		}
		inline PString GetClassNameById(index_t id)
		{
			PTypeNode n = GetGlobleLibrary().GetTypeNodeByInfo(id);
			if (n.IsNull())
			{
				return Type::GetTypeCommonInfoRef()[id].Name;
			}
			return n.GetName();
		}
	}
#ifdef SUPPORT_VARIADIC_TEMPLATES
	template<class ReturnType, class ...ArgumentsType>ReturnType PObject::DynamicCall(PString const&functionName, ArgumentsType...args)const
	{
		Reflection::PTypeNode tn = Reflection::GetGlobleLibrary().GetTypeNodeByInfo(GetType());
		if (tn.IsNull())throw PException(L"类库中找不到指定的类型");
		Reflection::PFunctionNode node = tn.FindNodeByNameInClass(functionName).CastTo<Reflection::PFunctionNode>();
		if (node.IsNull())throw PException(L"类型节点中找不到指定名称的函数");
		return Reflection::FunctionNodeFastCall <ReturnType( ArgumentsType...) >::FastCall(node,this, args...);
	}
#else
#define TMPCT(x) ,class T##x
#define TMPT(x) ,T##x
#define TMPTt(x) ,T##x t##x
#define TMPt(x) ,t##x
#define TMPF(x)\
	template<class ReturnType MF3_RepeatAsc(TMPCT,2,x)>ReturnType PObject::DynamicCall(PString const&functionName MF3_RepeatAsc(TMPTt,2,x))const{\
		Reflection::PTypeNode tn = Reflection::GetGlobleLibrary().GetTypeNodeByInfo(GetType());\
		if (tn.IsNull())throw PException(L"类库中找不到指定的类型");\
		Reflection::PFunctionNode node = tn.FindNodeByNameInClass(functionName).CastTo<Reflection::PFunctionNode>();\
		if (node.IsNull())throw PException(L"类型节点中找不到指定名称的函数");\
		return Reflection::FunctionNodeFastCall <ReturnType( MF4_RepeatAsc_(T,,2,x)) >::FastCall(node, this MF3_RepeatAsc(TMPt,2,x));\
	}
	MF2_Repeatb(TMPF, 30)
#undef TMPCT
#undef TMPT
#undef TMPTt
#undef TMPt
#undef TMPF
#endif
}
